﻿using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Scripting.Hosting;
using Newtonsoft.Json;
using IronPython.Hosting;

namespace YacGE.Script
{
    public class ScriptManager
    {
        private readonly Dictionary<String, Func<object, object, object, bool>> _functionList =
            new Dictionary<string, Func<object, object, object, bool>>();

        ScriptScope scope = null;

        public bool Add(String functionName, Func<Object, Object, Object, bool> function)
        {
            if (_functionList.ContainsKey(functionName))
            {
                _functionList.Remove(functionName);
                _functionList.Add(functionName, function);
                return true;
            }
            _functionList.Add(functionName, function);
            return false;
        }

        public Func<object, object, object, bool> GetFunction(string functionName)
        {
            return _functionList.ContainsKey(functionName) ? _functionList[functionName] : null;
        }

        public bool HasFunction(string functionName)
        {
            return _functionList.ContainsKey(functionName);
        }

        public void LoadFromString(string pyScr, string mapName)
        {
            var scriptLoadingHelper = JsonConvert.DeserializeObject<ScriptLoadingHelper>(pyScr);

            var path = @"Maps/" + mapName + @"/scripts/" + scriptLoadingHelper.PythonSource;
            TextReader textReader = new StreamReader(path);
            var pythonFile = textReader.ReadToEnd();
            textReader.Close();

            var engine = Python.CreateEngine();
            if(scope == null)
                scope = engine.CreateScope();
            var source = engine.CreateScriptSourceFromFile(@"Maps/" + mapName + @"/scripts/" + scriptLoadingHelper.PythonSource);

            source.Execute(scope);

            foreach (var functionName in scriptLoadingHelper.FunctionNameList)
            {
                if (!scope.ContainsVariable(functionName)) continue;

                Func<object, object, object, bool> temp = scope.GetVariable(functionName);
                Add(functionName, temp);
            }
        }

        public void LoadFromFile(string filePath, string mapName)
        {
            TextReader textReader = new StreamReader(filePath);

            var pyScr = textReader.ReadToEnd();

            textReader.Close();

            LoadFromString(pyScr, mapName);
        }
    }
}